﻿using System;
using System.Collections.Generic;

namespace RrslLite.Dsl
{
    public abstract class BatchCallBuilder<TTarget> : IBatchCallBuilder<TTarget> where TTarget : class
    {
        private readonly BatchBuilder _batchBuilder;
        private readonly Batch _parentBatch;

        public BatchCallBuilder(BatchBuilder batchBuilder)
        {
            _batchBuilder = batchBuilder;
            _parentBatch = _batchBuilder.CurrentBatch;
        }

        public IBatchCallBuilder<TTarget> WithQuery<TResult>(Func<TTarget, TResult> call, Action<TResult> handler)
        {
            var batchItem = CreateBatchFuncCall(call, handler);
            _parentBatch.Calls.Add(batchItem);

            return this;
        }

        public IBatchCallBuilder<TTarget> WithCommand(Action<TTarget> call, Action handler)
        {
            var batchItem = CreateBatchVoidCall(call, handler);
            _parentBatch.Calls.Add(batchItem);

            return this;
        }

        public IBatchCallBuilder<TTarget> WhenCompleted(Action<IEnumerable<BatchCallResult>> completedAction)
        {
            CurrentBatch.WhenCompletedCall(completedAction);

            return this;
        }

        public IBatchCallBuilder<TTarget1> Call<TTarget1>() where TTarget1 : class
        {
            return _batchBuilder.Call<TTarget1>();
        }

        public Batch CurrentBatch
        {
            get { return _parentBatch; }
        }

        public void Execute()
        {
            _batchBuilder.Execute();
        }

        protected abstract BatchFuncCall<TResult> CreateBatchFuncCall<TResult>(Func<TTarget, TResult> call,
                                                                               Action<TResult> handler);

        protected abstract BatchVoidCall CreateBatchVoidCall(Action<TTarget> call, Action handler);

    }
}